#include <arch.h>
#include <asm_macros.h>



/**
 * @brief Undefined instruction exception handler
 *
 * An undefined instruction (UNDEF) exception is generated when an undefined
 * instruction, or a VFP instruction when the VFP is not enabled, is
 * encountered.
 */
func arm_undef_instruction
	/*
	 * The undefined instruction address is offset by 2 if the previous
	 * mode is Thumb; otherwise, it is offset by 4.
	 */
	push {r0}
	mrs r0, spsr
	tst r0, #T_BIT
	subeq lr, #4	/* ARM   (!T_BIT) */
	subne lr, #2	/* Thumb (T_BIT) */
	pop {r0}

    exception_entry MODE32_und
    bl plat_handle_exception
    exception_exit

endfunc arm_undef_instruction


/**
 * @brief Prefetch abort exception handler
 *
 * A prefetch abort (PABT) exception is generated when the processor marks the
 * prefetched instruction as invalid and the instruction is executed.
 */
func arm_prefetch_abort
	/*
	 * The faulting instruction address is always offset by 4 for the
	 * prefetch abort exceptions.
	 */
	sub lr, #4

	exception_entry MODE32_abt
    bl plat_handle_exception
	exception_exit

endfunc arm_prefetch_abort

/**
 * @brief Data abort exception handler
 *
 * A data abort (DABT) exception is generated when an error occurs on a data
 * memory access. This exception can be either synchronous or asynchronous,
 * depending on the type of fault that caused it.
 */
func arm_data_abort
	/*
	 * The faulting instruction address is always offset by 8 for the data
	 * abort exceptions.
	 */
	sub lr, #8

	exception_entry MODE32_abt
    bl plat_handle_exception
	exception_exit

endfunc arm_data_abort

/**
 * @brief irq handle
 */
func arm_handle_irq
	/*
	 * The faulting instruction address is always offset by 4 for the
	 * prefetch abort exceptions.
	 */
	sub lr, #4

	exception_entry MODE32_irq
    bl plat_handle_interrupt
	exception_exit

endfunc arm_handle_irq

/**
 * @brief fiq handle
 */
func arm_handle_fiq
	/*
	 * The faulting instruction address is always offset by 4 for the
	 * prefetch abort exceptions.
	 */
	sub lr, #4

	exception_entry MODE32_fiq
    bl plat_handle_exception
	exception_exit

endfunc arm_handle_fiq

 .global vector_table

/* -----------------------------------------------------
 * Setup the vector table to support SVC & MON mode.
 * -----------------------------------------------------
 */
vector_base vector_table
    ldr pc, =entrypoint             /*                   offset 0 */
    ldr pc, =arm_undef_instruction  /* undef instruction offset 4 */
    nop                             /* svc               offset 8 */
    ldr pc, =arm_prefetch_abort     /* prefetch abort offset  0xc */
    ldr pc, =arm_data_abort         /* data abort     offset 0x10 */
    nop                             /*                offset 0x14 */
    ldr pc, =arm_handle_irq         /* IRQ            offset 0x18 */
    ldr pc, =arm_handle_fiq         /* FIQ            offset 0x1c */

